<template>
  <div class="shutdown-statistics">
    <el-container>
      <el-header style="height: 10vh">
        <div class="common-div-card sds2280-header">
          <el-form :inline="true" :model="searchForm" class="sds2280-header-form">
            <el-form-item label="原料卷号">
              <el-input v-model="searchForm.coldCoilId" placeholder="请输入原料卷号" clearable />
            </el-form-item>
            <el-form-item label="开始时间">
              <el-date-picker v-model="searchForm.startTime" type="datetime" placeholder="开始时间" value-format="YYYY-MM-DD HH:mm:ss" />
            </el-form-item>
            <el-form-item label="结束时间">
              <el-date-picker v-model="searchForm.endTime" type="datetime" placeholder="结束时间" value-format="YYYY-MM-DD HH:mm:ss" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleSearch">查询</el-button>
              <el-button @click="handleReset">重置</el-button>
              <el-button type="primary" @click="handleExport">导出</el-button>
            </el-form-item>
          </el-form>
        </div>
      </el-header>
      <el-main style="height: 52vh; margin-top: -1vh">
        <el-col>
          <el-row>
            <div style="width: 100%" class="common-div-card sds2280-table">
              <el-table
                :data="tableData"
                border
                :header-cell-style="{ background: '#eef1f6', color: '#606266', textAlign: 'center' }"
                :cell-style="{ textAlign: 'center' }"
                :stripe="true"
                v-loading="tableLoading"
                :show-overflow-tooltip="true"
                ref="tableRef"
              >
                <el-table-column type="index" label="序号" width="80" />
                <el-table-column label="班组" width="100">
                  <template #default="scope">
                    <span>{{ scope.row.shift }} {{ scope.row.crew }}</span>
                  </template>
                </el-table-column>
                <el-table-column prop="duration" label="停机时长[min]" width="100px" />
                <el-table-column prop="coldCoilId" label="原料卷号" width="140px" />
                <el-table-column prop="stopStartTime" label="停机开始时间" width="180px" />
                <el-table-column prop="stopEndTime" label="停机结束时间" width="180px" />
                <el-table-column prop="stopType" label="停机类型" width="120px" />
                <el-table-column prop="reason" label="停机原因" width="120px" />
                <el-table-column prop="speedpos" label="速度位置" width="120px" />
                <el-table-column prop="respon" label="责任归属" width="120px" />
                <el-table-column prop="stopB" label="停机大类" width="120px" />
                <el-table-column prop="stopS" label="停机细分类" width="120px" />
                <el-table-column prop="remark" label="备注" min-width="300" />
                <el-table-column label="操作" width="80" fixed="right">
                  <template #default="scope">
                    <el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-row>
          <el-row>
            <!-- 分页区域 -->
            <div class="common-div-card sds2280-pagination">
              <el-pagination
                v-model:current-page="pagination.currentPage"
                v-model:page-size="pagination.pageSize"
                :page-sizes="[10, 20, 30, 50]"
                layout="total, sizes, prev, pager, next, jumper"
                :total="pagination.total"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                background
              />
            </div>
          </el-row>
        </el-col>
      </el-main>
      <el-footer style="height: 30vh; margin-top: -2vh">
        <el-row>
          <el-col :span="8">
            <div class="common-div-card stacked-bar-chart-card">
              <graph-stacked-bar :datax="stackedDatax" :data="stackedData" :dataName="stackedName" :title="stackedTitle" :max="stackedMax" />
            </div>
          </el-col>
          <el-col :span="8">
            <div class="common-div-card multi-bar-chart-card">
              <graph-bar-other
                :title="multiTitle"
                :data-name="multiDataName"
                :data1="multiDataTotal"
                :data2="multiDataCrewA"
                :data3="multiDataCrewB"
                :data4="multiDataCrewC"
                :data5="multiDataCrewD"
                :datax="multiDatax"
                :max="multiMax"
              />
            </div>
          </el-col>
          <el-col :span="8">
            <div class="common-div-card comparison-chart-card">
              <graph-bar-other
                :data-name="comparisonDataName"
                :data1="comparisonDataStandard"
                :data2="comparisonDataCalendar"
                :datax="comparisonDatax"
                :title="comparisonTitle"
                :max="comparisonMax"
              />
            </div>
          </el-col>
        </el-row>
      </el-footer>
    </el-container>
  </div>

  <el-dialog
    v-model="detailDialogVisible"
    :before-close="handleClose"
    :close-on-click-modal="false"
    ref="detailDialogRef"
    @closed="cancel"
    class="detailDialog"
  >
    <div>
      <el-form :model="dialogForm" label-width="auto" ref="dialogFormRef">
        <el-form-item label="班组">
          <el-text>{{ dialogForm.shift }}{{ dialogForm.crew }}</el-text>
        </el-form-item>
        <el-form-item label="停机时长[min]">
          <el-text>{{ dialogForm.duration }}</el-text>
        </el-form-item>
        <el-form-item label="原料卷号">
          <el-text>{{ dialogForm.coldCoilId }}</el-text>
        </el-form-item>
        <el-form-item label="停机开始时间">
          <el-text>{{ dialogForm.stopStartTime }}</el-text>
        </el-form-item>
        <el-form-item label="停机结束时间">
          <el-text>{{ dialogForm.stopEndTime }}</el-text>
        </el-form-item>
        <el-form-item label="停机类型">
          <el-text>{{ dialogForm.stopType }}</el-text>
        </el-form-item>
        <el-form-item label="停机原因">
          <el-text>{{ dialogForm.reason }}</el-text>
        </el-form-item>
        <el-form-item label="速度位置">
          <el-text>{{ dialogForm.speedpos }}</el-text>
        </el-form-item>
        <el-form-item label="责任归属">
          <el-input v-model="dialogForm.respon" placeholder="请输入变量名" />
        </el-form-item>
        <el-form-item label="停机大类">
          <el-select v-model="dialogForm.stopB" placeholder="数据源" clearable>
            <el-option v-for="item in mainCategoryOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="停机细分类">
          <el-select v-model="dialogForm.stopS" placeholder="数据源" clearable>
            <el-option v-for="item in subCategoryOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="dialogForm.remark" type="textarea" :rows="4" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="dialogFormSubmit"> 提交 </el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
  import { ref, reactive, onMounted } from 'vue';
  import dayjs from 'dayjs';
  import { ElMessageBox, ElNotification } from 'element-plus';
  import GraphStackedBar from '../../components/GraphStackedBar.vue';
  import GraphBarOther from '../../components/GraphBarOther.vue';
  import { showdownApi } from '/@/api/report/shutdown/index';
  import * as XLSX from 'xlsx';

  // 搜索表单数据
  const searchForm = reactive({
    startTime: '',
    endTime: '',
    coldCoilId: '',
  });

  const tableLoading = ref(false);
  const tableRef = ref();
  const detailDialogVisible = ref(false);

  // 停机大类
  const mainCategoryOptions = ref([
    { label: '生产准备', value: '生产准备' },
    { label: '生产故障', value: '生产故障' },
    { label: '设备故障', value: '设备故障' },
    { label: '轧辊故障', value: '轧辊故障' },
    { label: '实绩定修', value: '实绩定修' },
    { label: '停机点检', value: '停机点检' },
    { label: '外部原因', value: '外部原因' },
    { label: '计划停', value: '计划停' },
    { label: '待料', value: '待料' },
    { label: '运转故障', value: '运转故障' },
    { label: '试验料', value: '试验料' },
    { label: '其它', value: '其它' },
  ]);

  // 停机细分类
  const subCategoryOptions = ref([
    { label: '生产准备-换工作辊(计划)', value: '生产准备-换工作辊(计划)' },
    { label: '生产准备-换工作辊(非计划)', value: '生产准备-换工作辊(非计划)' },
    { label: '生产准备-工艺调整', value: '生产准备-工艺调整' },
    { label: '生产准备-其它', value: '生产准备-其它' },
    { label: '生产故障', value: '生产故障' },
    { label: '机械故障', value: '机械故障' },
    { label: '电气故障', value: '电气故障' },
    { label: '轧辊故障', value: '轧辊故障' },
    { label: '能介故障', value: '能介故障' },
    { label: '实际定修', value: '实际定修' },
    { label: '停机点检-机械', value: '停机点检-机械' },
    { label: '停机点检-电气', value: '停机点检-电气' },
    { label: '计划停', value: '计划停' },
    { label: '待料', value: '待料' },
    { label: '其它-能源介质', value: '其它-能源介质' },
    { label: '其它-外部因素', value: '其它-外部因素' },
  ]);

  // 表格数据
  const tableData = ref([]);
  // 图表数据
  // 动态堆叠柱状图数据
  const stackedData = ref<any[]>([]);
  const stackedName = ref<any[]>([]);
  const stackedDatax = ref<any[]>([]);
  const stackedTitle = ref('近12个月轧机停机次数-各类停机原因');
  const stackedMax = ref(0);

  // 图表数据
  const multiTitle = ref('近12个月各班组轧机停机次数');
  const multiDataName = ref(['总体', '班组A', '班组B', '班组C', '班组D']);
  const multiDataTotal = Array(12).fill(0);
  const multiDataCrewA = Array(12).fill(0);
  const multiDataCrewB = Array(12).fill(0);
  const multiDataCrewC = Array(12).fill(0);
  const multiDataCrewD = Array(12).fill(0);
  const multiDatax = getLast12Months();
  const multiMax = ref(0);

  const comparisonTitle = ref('近12个月标准/日历作业率');
  const comparisonDataName = ref(['标准作业率', '日历作业率']);
  const comparisonDataStandard = Array(12).fill(0);
  const comparisonDataCalendar = Array(12).fill(0);
  const comparisonDatax = getLast12Months();
  const comparisonMax = ref(0);

  // dialog数据
  const dialogForm = reactive({
    indocno: 0, // 编号
    shift: '中', // 班次
    crew: '丙', // 班组
    seqid: '',
    calCoilId: '', // 连退出口卷号
    coldCoilId: '', //停机开始时间对应的原料卷号
    reason: '', //停机原因
    speedpos: '', // 速度位置
    duration: 2.55, // 停机时长
    stopStartTime: '', //停机开始时间
    stopEndTime: '', //停机结束时间
    stopType: '', //停机类型 停机和慢速
    respon: '原料', //责任方
    stopB: '外部原因', //停机大类
    stopS: '其它小原因素', // 停机细分类
    remark: '原料与尺寸不符合规范', //备注
    dbegin: '', //查询开始时间
    dend: '', //查询结束时间
  });

  // 分页大小变化
  const handleSizeChange = (val: number) => {
    pagination.pageSize = val;
    fetchTableData();
  };

  // 页码变化
  const handleCurrentChange = (val: number) => {
    pagination.currentPage = val;
    fetchTableData();
  };

  // --- Pagination ---
  const pagination = reactive({
    currentPage: 1,
    pageSize: 10,
    total: tableData.value.length,
  });

  // 搜索方法
  const handleSearch = async () => {
    pagination.currentPage = 1;
    await fetchTableData();
    await fetchGraphData();
  };

  // 重置方法
  const handleReset = async () => {
    searchForm.startTime = '';
    searchForm.endTime = '';
    pagination.currentPage = 1;
    await fetchTableData();
    await fetchGraphData();
  };

  // 导出方法
  const handleExport = () => {
    if (!tableData.value.length) {
      ElNotification({
        title: 'Error',
        message: '导出Excel失败: 当前暂无数据',
        type: 'error',
      });
      return;
    }

    try {
      // 动态获取表格列配置
      let columns = tableRef.value?.columns;

      if (!columns || !(Array.isArray(columns) && columns.length)) {
        ElNotification({
          title: 'Error',
          message: '导出Excel失败: 表格列配置错误',
          type: 'error',
        });
        return;
      }

      // 添加新的属性到 headerMap
      const headerMap: Record<string, string> = {
        index: '序号',
        shift: '班次',
        crew: '班组',
      };

      columns = columns.filter((column: any) => {
        return column.property;
      });

      // 构建字段到标签的映射
      columns.forEach((column: any) => {
        if (column.property) {
          headerMap[column.property] = column.label;
        }
      });

      // 构建字段名数组
      const columnProperties = Object.keys(headerMap);

      // 过滤 tableData 中不在 columns 配置中的字段
      const filteredTableData = tableData.value.map((row: any, rowIndex: number) => {
        const filteredRow: any = { index: rowIndex + 1 };
        columnProperties.forEach((property: string) => {
          if (row[property] !== undefined) {
            filteredRow[property] = row[property];
          }
        });
        return filteredRow;
      });

      // 转换数据为 worksheet
      const ws = XLSX.utils.json_to_sheet(filteredTableData, { header: columnProperties });

      // 添加中文表头
      const headerRow = Object.values(headerMap);
      XLSX.utils.sheet_add_aoa(ws, [headerRow], { origin: 'A1' });

      // 创建 workbook 并添加 worksheet
      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');

      // 格式化日期和时间
      const formattedDateTime = new Date()
        .toLocaleString('zh-CN', {
          year: 'numeric',
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit',
          hour12: false,
        })
        .replace(/\//g, '-')
        .replace(/\s/g, '_')
        .replace(/:/g, '-');

      // 生成 Excel 文件并下载
      XLSX.writeFile(wb, '2280酸轧停机明细及统计' + formattedDateTime + '.xlsx');
      ElMessage.success('导出成功');
    } catch (error: any) {
      ElMessage.error('导出Excel失败: ' + error.message);
      console.error('导出Excel时出错:', error);
    }
  };

  // 编辑方法
  const handleEdit = (row: any) => {
    detailDialogVisible.value = true;
    Object.assign(dialogForm, { ...row });
  };

  // 详情弹窗关闭事件
  const handleClose = (done: () => void) => {
    ElMessageBox.confirm('确定要放弃当前更改吗?')
      .then(() => {
        cancel();
      })
      .catch(() => {
        // catch error
      });
  };

  // 详情弹窗取消事件
  const cancel = () => {
    detailDialogVisible.value = false;
  };

  // 编辑提交
  const dialogFormSubmit = async () => {
    try {
      const param = {
        pageIndex: pagination.currentPage,
        pageSize: pagination.pageSize,
        dbegin: searchForm.startTime, // 查询开始时间
        dend: searchForm.endTime, // 查询结束时间
        indocno: dialogForm.indocno,
        seqid: dialogForm.seqid,
        calCoilId: dialogForm.calCoilId,
        crew: dialogForm.crew,
        duration: dialogForm.duration,
        coldCoilId: dialogForm.coldCoilId,
        reason: dialogForm.reason,
        remark: dialogForm.remark,
        respon: dialogForm.respon,
        shift: dialogForm.shift,
        speedpos: dialogForm.speedpos,
        stopB: dialogForm.stopB,
        stopEndTime: dialogForm.stopEndTime,
        stopS: dialogForm.stopS,
        stopStartTime: dialogForm.stopStartTime,
        stopType: dialogForm.stopType,
      };
      await showdownApi.updateTbDowntimeCal1630(param).then((res) => {
        if (res.data.status != 2000) {
          throw new Error('数据登录失败：' + res.data.message);
        }
      });
    } catch (error: any) {
      detailDialogVisible.value = false;
      ElNotification({
        title: '数据获取失败',
        message: error.message ?? '',
        type: 'error',
        duration: 2000,
      });
      console.error('数据登录失败:', error);
    } finally {
      detailDialogVisible.value = false;
      ElNotification({
        title: 'Success',
        message: '数据登录成功',
        type: 'success',
      });
      fetchTableData();
    }
  };

  const fetchTableData = async () => {
    // 初始化数据
    try {
      tableLoading.value = true;
      const param = {
        pageIndex: pagination.currentPage,
        pageSize: pagination.pageSize,
        dbegin: searchForm.startTime, // 查询开始时间
        dend: searchForm.endTime, // 查询结束时间
        coldCoilId: searchForm.coldCoilId,
      };
      showdownApi.getTbDowntimeCal1630(param).then((res) => {
        if (res.data.status == 2000) {
          tableData.value = res.data.data.map((item: any) => {
            if (item.duration && typeof item.duration !== 'number') {
              throw new Error('停机时长数据类型错误');
            }
            const durationInMinutes = item.duration / 60;
            return {
              ...item,
              duration: Math.round(durationInMinutes * 100) / 100,
            };
          });
          pagination.total = res.data.count;
          ElNotification({
            title: 'Success',
            message: '数据获取成功',
            type: 'success',
          });
        } else {
          throw new Error('数据获取失败：' + res.data.message);
        }
      });
    } catch (error: any) {
      ElNotification({
        title: '数据获取失败',
        message: error.message ?? '',
        type: 'error',
        duration: 2000,
      });
    } finally {
      tableLoading.value = false;
    }
  };

  // 动态获取堆叠柱状图数据
  const getStackedBarData = async () => {
    const params: any = { year: searchForm.startTime ? dayjs(searchForm.startTime).format('YYYY') : dayjs().format('YYYY') };
    if (searchForm.coldCoilId) params.coldCoilId = searchForm.coldCoilId;
    const res = await showdownApi.tbDowntimeCal1630stops(params);
    if (res.data.status === 2000 && Array.isArray(res.data.data)) {
      const raw = res.data.data;
      // 1. 统计所有yearmonth和stops
      const allMonths = Array.from(new Set(raw.map((item: any) => item.yearmonth))).sort();
      const allStops = Array.from(new Set(raw.map((item: any) => item.stops)));
      // 2. 构建二维数组，确保每个series的data长度和allMonths一致
      const seriesData: number[][] = allStops.map(() => allMonths.map(() => 0));
      raw.forEach((item: any) => {
        const stopIdx = allStops.indexOf(item.stops);
        const monthIdx = allMonths.indexOf(item.yearmonth);
        if (stopIdx !== -1 && monthIdx !== -1) {
          seriesData[stopIdx][monthIdx] = Number(item.hours) || 0;
        }
      });
      stackedData.value = seriesData;
      stackedName.value = allStops;
      stackedDatax.value = allMonths;
      // 3. 计算max
      let max = 0;
      for (let i = 0; i < allMonths.length; i++) {
        let sum = 0;
        for (let j = 0; j < allStops.length; j++) {
          sum += seriesData[j][i];
        }
        if (sum > max) max = sum;
      }
      stackedMax.value = Math.max(Math.ceil(max * 1.3), 10);
    } else {
      stackedData.value = [];
      stackedName.value = [];
      stackedDatax.value = [];
      stackedMax.value = 0;
    }
  };

  // 近12个月各班组轧机停机次数
  const getCountGraph = async () => {
    try {
      const params: any = { year: searchForm.startTime ? dayjs(searchForm.startTime).format('YYYY') : dayjs().format('YYYY') };
      await showdownApi.getCountGraph1630(params).then((res) => {
        if (res.data.status != 2000) {
          throw new Error('数据获取失败：' + res.data.message);
        }
        const monthIndexMap = new Map<string, number>();
        multiDatax.forEach((month: any, index: number) => {
          monthIndexMap.set(month, index);
        });

        // 填充数据到对应数组
        res.data.data.forEach((item: any) => {
          const month = item.yearmonth;
          const crew = item.crew;
          const count = Number(item.count);

          const index = monthIndexMap.get(month);

          if (index !== undefined) {
            switch (crew) {
              case '总数':
                multiDataTotal[index] = count;
                break;
              case 'A':
                multiDataCrewA[index] = count;
                break;
              case 'B':
                multiDataCrewB[index] = count;
                break;
              case 'C':
                multiDataCrewC[index] = count;
                break;
              case 'D':
                multiDataCrewD[index] = count;
                break;
            }
          }
        });
        multiMax.value = Math.round(Math.max(...multiDataTotal) * 1.1);
      });
    } catch (error: any) {
      console.error(error);
      ElNotification({
        title: '停机次数统计图数据获取失败',
        message: error.message ?? '',
        type: 'error',
        duration: 2000,
      });
    } finally {
      tableLoading.value = false;
    }
  };

  // 近12个月标准/日历作业率
  const getCalendarGraph = async () => {
    try {
      const params: any = { year: searchForm.startTime ? dayjs(searchForm.startTime).format('YYYY') : dayjs().format('YYYY') };
      await showdownApi.getCalendarGraph1630(params).then((res) => {
        if (res.data.status != 2000) {
          throw new Error('数据获取失败：' + res.data.message);
        }
        const monthIndexMap = new Map<string, number>();
        comparisonDatax.forEach((month: any, index: number) => {
          monthIndexMap.set(month, index);
        });

        // 填充数据到对应数组
        res.data.data.forEach((item: any) => {
          const month = item.yearMonth;
          const std = item.standardRate;
          const calendar = item.calendarRate;

          const index = monthIndexMap.get(month);

          if (index != undefined) {
            comparisonDataStandard[index] = std;
            comparisonDataCalendar[index] = calendar;
          }
        });
        comparisonMax.value = Math.round(Math.max(...comparisonDataStandard, ...comparisonDataCalendar) * 1.1);
      });
    } catch (error: any) {
      console.error(error);
      ElNotification({
        title: '停机次数统计图数据获取失败',
        message: error.message ?? '',
        type: 'error',
        duration: 2000,
      });
    } finally {
      tableLoading.value = false;
    }
  };

  const fetchGraphData = async () => {
    getStackedBarData();
    getCountGraph();
    getCalendarGraph();
  };

  onMounted(() => {
    fetchTableData();
    fetchGraphData();
  });

  onUnmounted(() => {});

  // 获取月份YYYY-MM数组
  function getLast12Months(): string[] {
    const result: string[] = [];
    const currentDate = new Date();

    // 设置日期为12个月前的1号（避免月末日期跨月问题）
    const startDate = new Date(currentDate);
    startDate.setDate(1);
    startDate.setMonth(startDate.getMonth() - 11); // 12个月包含当前月，所以回退11个月

    // 临时日期用于循环
    const tempDate = new Date(startDate);

    // 循环生成12个月份（从最早月开始）
    for (let i = 0; i < 12; i++) {
      const year = tempDate.getFullYear();
      const month = tempDate.getMonth() + 1; // 月份从0开始需+1

      // 格式化为 YYYY-MM
      const formatted = `${year}-${month.toString().padStart(2, '0')}`;
      result.push(formatted);

      // 将日期前进到下个月
      tempDate.setMonth(tempDate.getMonth() + 1);
    }

    return result;
  }
</script>
<style lang="less" scoped>
  @border-radius: 8px;
  @primary-color: #2c69e8;
  @box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  @box-shadow-hover: 0 8px 32px rgba(0, 0, 0, 0.12);
  @border:1px solid #dcdfe6;

  .shutdown-statistics {
    background-color: #fff;
  }

  .common-div-card {
    box-shadow: @box-shadow;
    transition: 0.3s;
    border-radius: @border-radius;
    border: @border;

    // 悬停状态
    &:hover {
      box-shadow: @box-shadow-hover;
    }
  }

  .sds2280-header {
    display: flex;
    flex: 1;
    justify-content: flex-start;
    align-items: center;
    padding: 20px;
    height: 10vh;
  }

  .sds2280-header-form {
    display: flex;
    align-items: center;
    gap: 20px;
  }

  .sds2280-table {
    width: 100%;
    height: 40vh;
    padding: 10px;
    margin-top: -1vh;

    .el-table {
      height: calc(40vh - 20px);
    }
  }

  .sds2280-pagination {
    width: 100%;
    height: 6vh;
    display: flex;
    justify-content: flex-end;
    padding: 20px;
  }

  .stacked-bar-chart-card,
  .multi-bar-chart-card,
  .comparison-chart-card {
    height: 30vh;
    width: 100%;
  }
</style>
